using ServiceStack.Model;
using ServiceStack.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace ServiceStack
{
	public static class IdUtils<T>
	{
		[CompilerGenerated]
		[Serializable]
		private sealed class <>c
		{
			public static readonly IdUtils<T>.<>c <>9 = new IdUtils<T>.<>c();
			public static Func<Attribute, bool> <>9__1_2;
			internal bool cctor>b__1_0(Type t, object critera)
			{
				return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IHasId<>);
			}
			internal bool cctor>b__1_1(PropertyInfo pi)
			{
				IEnumerable<Attribute> arg_25_0 = pi.AllAttributes<Attribute>();
				Func<Attribute, bool> arg_25_1;
				if ((arg_25_1 = IdUtils<T>.<>c.<>9__1_2) == null)
				{
					arg_25_1 = (IdUtils<T>.<>c.<>9__1_2 = new Func<Attribute, bool>(IdUtils<T>.<>c.<>9.<.cctor>b__1_2));
				}
				return arg_25_0.Any(arg_25_1);
			}
			internal bool cctor>b__1_2(Attribute attr)
			{
				return attr.GetType().Name == "PrimaryKeyAttribute";
			}
			internal object cctor>b__1_3(T x)
			{
				PropertyInfo idProperty = x.GetType().GetIdProperty();
				if (idProperty != null && idProperty.GetMethodInfo(true) != null)
				{
					return x.GetObjectId();
				}
				return x.GetHashCode();
			}
			internal object cctor>b__1_4(T x)
			{
				return x.GetHashCode();
			}
		}
		internal static Func<T, object> CanGetId;
		static IdUtils()
		{
			if (typeof(T).FindInterfaces(new TypeFilter(IdUtils<T>.<>c.<>9.<.cctor>b__1_0), null).Length != 0)
			{
				IdUtils<T>.CanGetId = new Func<T, object>(HasId<T>.GetId);
				return;
			}
			if (typeof(T).IsClass() || typeof(T).IsInterface)
			{
				using (IEnumerator<PropertyInfo> enumerator = typeof(T).GetPublicProperties().Where(new Func<PropertyInfo, bool>(IdUtils<T>.<>c.<>9.<.cctor>b__1_1)).GetEnumerator())
				{
					if (enumerator.MoveNext())
					{
						IdUtils<T>.CanGetId = StaticAccessors<T>.ValueUnTypedGetPropertyTypeFn(enumerator.Current);
						return;
					}
				}
				PropertyInfo idProperty = typeof(T).GetIdProperty();
				if (idProperty != null && idProperty.GetMethodInfo(true) != null)
				{
					IdUtils<T>.CanGetId = new Func<T, object>(HasPropertyId<T>.GetId);
					return;
				}
			}
			if (typeof(T) == typeof(object))
			{
				IdUtils<T>.CanGetId = new Func<T, object>(IdUtils<T>.<>c.<>9.<.cctor>b__1_3);
				return;
			}
			IdUtils<T>.CanGetId = new Func<T, object>(IdUtils<T>.<>c.<>9.<.cctor>b__1_4);
		}
		public static object GetId(T entity)
		{
			return IdUtils<T>.CanGetId(entity);
		}
	}
	public static class IdUtils
	{
		public const string IdField = "Id";
		public static object GetObjectId(this object entity)
		{
			return entity.GetType().GetIdProperty().GetMethodInfo(true).Invoke(entity, new object[0]);
		}
		public static object ToId<T>(this T entity)
		{
			return entity.GetId<T>();
		}
		public static string ToUrn<T>(this T entity)
		{
			return entity.CreateUrn<T>();
		}
		public static string ToSafePathCacheKey<T>(this string idValue)
		{
			return IdUtils.CreateCacheKeyPath<T>(idValue);
		}
		public static string ToUrn<T>(this object id)
		{
			return IdUtils.CreateUrn<T>(id);
		}
		public static object GetId<T>(this T entity)
		{
			return IdUtils<T>.GetId(entity);
		}
		public static string CreateUrn<T>(object id)
		{
			return string.Format("urn:{0}:{1}", typeof(T).Name.ToLowerInvariant(), id);
		}
		public static string CreateUrn(Type type, object id)
		{
			return string.Format("urn:{0}:{1}", type.Name.ToLowerInvariant(), id);
		}
		public static string CreateUrn<T>(this T entity)
		{
			object id = entity.GetId<T>();
			return string.Format("urn:{0}:{1}", typeof(T).Name.ToLowerInvariant(), id);
		}
		public static string CreateCacheKeyPath<T>(string idValue)
		{
			if (idValue.Length < 4)
			{
				idValue = idValue.PadLeft(4, '0');
			}
			idValue = idValue.Replace(" ", "-");
			string name = typeof(T).Name;
			string text = idValue.Substring(0, 2);
			string text2 = idValue.Substring(2, 2);
			return string.Format("{1}{0}{2}{0}{3}{0}{4}", new object[]
			{
				PclExport.Instance.DirSep,
				name,
				text,
				text2,
				idValue
			});
		}
		public static PropertyInfo GetIdProperty(this Type type)
		{
			PropertyInfo[] propertyInfos = type.GetPropertyInfos();
			for (int i = 0; i < propertyInfos.Length; i++)
			{
				PropertyInfo propertyInfo = propertyInfos[i];
				if (string.Equals("Id", propertyInfo.Name, StringComparison.OrdinalIgnoreCase))
				{
					return propertyInfo;
				}
			}
			return null;
		}
	}
}
